package view;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.Frame;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSeparator;
import javax.swing.JSplitPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;
import javax.swing.border.EmptyBorder;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.filechooser.FileFilter;

import model.Movie;
import controller.MainController;

/**.
 * MainView
 * @author jaubertbenjamin
 *
 */
public class MainView extends JFrame {

	private static final long serialVersionUID = -3078792654413858428L;
	private JPanel contentPanel;
	private JTextField searchTextField;
	private JMenuBar menuBar;
	private JMenu menuOption;
	private JMenuItem menuAddNewMovies;
	private JTabbedPane tabbedPane;
	private JSplitPane LibraryPanel;
	private JPanel leftPanel;
	private JScrollPane innerLeftScrollPanel;
	private JList list;
	private JPanel rightPanel;
	private JScrollPane innerRightScrollPanel;
	private JPanel innerPanel;
	private JSeparator separator;
	private JPanel moviesNotFoundPanel;
	private JTextArea plotTextArea;
	private ListSelectionListener listSelectionListener;
	private JLabel releaseLabel;
	private JLabel dvdLabel;
	private JLabel lblTheatre;
	private JLabel dvdRelease;
	private JLabel theatreRelease;
	private JLabel lblRuntime;
	private JLabel runtime;
	private JLabel plotLabel;
	private URL url;
	private Image image;
	private JLabel poster;
	private JLabel ratingLabel;
	private JLabel criticsLabel;
	private JLabel audienceLabel;
	private JLabel critics;
	private JLabel audience;
	private JLabel criticLabel;
	private JTextArea critic;
	private JLabel imageCritic;
	private JLabel genreLabel;
	private JLabel genres;
	private JLabel actorsLabel;
	private JLabel actors;
	private JLabel lblNewLabel;
	private JLabel directors;
	private JLabel labelWriters;
	private JLabel writers;
	private JLabel classifiedLabel;
	private JLabel classified;
	private JLabel productionLabel;
	private JLabel production;
	private JLabel boxOfficeLabel;
	private JLabel boxOffice;
	private JLabel titleLabel;
	private JMenu menuExportLibrary;
	private JMenuItem menuJson;
	private JMenuItem menuXml;
	private JFileChooser dialogue;
	private JFileChooser loadDialogue;
	private JFileChooser saveDialogue;
	private String[] array;
	private JMenuItem menuOrganizeMoviesLibrary;
	private JLabel ratingImage;
	private JScrollPane scrollPanel;
	private JList movieNotFoundList;
	private String[] arrayMovieNotFound;
	private JMenu menuLoadLibrary;
	private JMenuItem menuLoadJSon;
	private JMenuItem menuLoadXML;

	/**
	 * Create the frame.
	 */
	public MainView(final String[] ar, String[] MoviesNotFound, Movie movie) {
		setTitle("- WOOVEE -");
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(100, 100, 450, 300);
		setExtendedState(Frame.MAXIMIZED_BOTH);
		array = ar;
		arrayMovieNotFound = MoviesNotFound;

		setMenu();

		contentPanel = new JPanel();
		contentPanel.setBackground(Color.DARK_GRAY);
		contentPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
		contentPanel.setLayout(new BorderLayout(0, 0));
		setContentPane(contentPanel);

		tabbedPane = new JTabbedPane(JTabbedPane.TOP);
		contentPanel.add(tabbedPane, BorderLayout.CENTER);

		LibraryPanel = new JSplitPane();
		tabbedPane.addTab("Movies Library", null, LibraryPanel, null);
		LibraryPanel.setEnabled(false);
		LibraryPanel.setBackground(Color.DARK_GRAY);

		leftPanel = new JPanel();
		leftPanel.setBackground(Color.GRAY);
		LibraryPanel.setLeftComponent(leftPanel);
		leftPanel.setLayout(new BorderLayout(0, 0));

		searchTextField = new JTextField();
		leftPanel.add(searchTextField, BorderLayout.NORTH);
		searchTextField.setColumns(10);
		searchTextField.getDocument().addDocumentListener(new DocumentListener() {
			public void insertUpdate(final DocumentEvent e) {
				MainController.findMovies(searchTextField.getText());
			}
			public void changedUpdate(final DocumentEvent arg0) {
				//change
			}
			public void removeUpdate(final DocumentEvent arg0) {
				MainController.getFullLibrary();
			}
		});

		innerLeftScrollPanel = new JScrollPane();
		leftPanel.add(innerLeftScrollPanel, BorderLayout.CENTER);
		list = new JList();
		list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);;
		if(array!=null)
			 list.setListData(array);
		list.setBackground(Color.GRAY);
		innerLeftScrollPanel.setViewportView(list);
		
		list.addMouseListener(new MouseAdapter() {
		    public void mouseClicked(MouseEvent evt) {
		        if (evt.getClickCount() == 2) {
		        	if(array[list.locationToIndex(evt.getPoint())]!=null)
		        		MainController.launchMovie(array[list.locationToIndex(evt.getPoint())]);
		        } else if(evt.getClickCount() == 1){
		        	if(array[list.locationToIndex(evt.getPoint())]!=null)
		        			SetMovieInfo(MainController.getMovie(array[list.locationToIndex(evt.getPoint())]));
		        }
		    }
		});
		
	   listSelectionListener = new ListSelectionListener() {
		    public void valueChanged(ListSelectionEvent listSelectionEvent) {
		        if ((!listSelectionEvent.getValueIsAdjusting())&&((list.getSelectedIndex()!=-1))) {
		        	if(array[list.getSelectedIndex()]!=null)
		        		SetMovieInfo(MainController.getMovie(array[list.getSelectedIndex()]));
		        }
		    }
		};
		list.addListSelectionListener(listSelectionListener);
		    
		rightPanel = new JPanel();
		rightPanel.setBackground(Color.GRAY);
		LibraryPanel.setRightComponent(rightPanel);
		rightPanel.setLayout(new BorderLayout(0, 0));
		
		innerRightScrollPanel = new JScrollPane();
		rightPanel.add(innerRightScrollPanel);
		
		SetMoviePanel();
		
		moviesNotFoundPanel = new JPanel();
		moviesNotFoundPanel.setBackground(Color.GRAY);
		tabbedPane.addTab("Movies Not Found", null, moviesNotFoundPanel, null);
		moviesNotFoundPanel.setLayout(new BorderLayout(0, 0));
		
		scrollPanel = new JScrollPane();
		moviesNotFoundPanel.add(scrollPanel, BorderLayout.CENTER);
		
		movieNotFoundList = new JList();
		movieNotFoundList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		movieNotFoundList.setBackground(Color.GRAY);
		if(arrayMovieNotFound!=null)
			movieNotFoundList.setListData(arrayMovieNotFound);
		scrollPanel.setViewportView(movieNotFoundList);
		
		movieNotFoundList.addMouseListener(new MouseAdapter() {
		    public void mouseClicked(MouseEvent evt) {
		        if (evt.getClickCount() == 2) {
		        	if(arrayMovieNotFound[list.locationToIndex(evt.getPoint())]!=null)
		        		MainController.launchMovieByPath(arrayMovieNotFound[list.locationToIndex(evt.getPoint())]);
		        } 
		    }
		});
		
		if(movie!=null)
			SetMovieInfo(movie);
		
		setVisible(true);
	}
	
	/**
	 * Set the menu
	 */
	private void setMenu(){
		menuBar = new JMenuBar();
		menuBar.setBackground(Color.GRAY);
		setJMenuBar(menuBar);
		
		menuOption = new JMenu("Option");
		menuOption.setBackground(Color.GRAY);
		menuBar.add(menuOption);
		
		menuAddNewMovies = new JMenuItem("Add new movies");
		menuAddNewMovies.setBackground(Color.WHITE);
		menuOption.add(menuAddNewMovies);
		menuAddNewMovies.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				MainController.addNewMovies(setDirectoryChooser());
			}
		});
		
		menuLoadLibrary = new JMenu("Load Library");
		menuOption.add(menuLoadLibrary);
		
		menuLoadJSon = new JMenuItem("JSON");
		menuLoadLibrary.add(menuLoadJSon);
		menuLoadJSon.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				String path = setFileLoadChooser("json");
				if(path!=null)
					MainController.loadJSON(path);
			}
		});
		menuLoadXML = new JMenuItem("XML");
		menuLoadLibrary.add(menuLoadXML);
		menuLoadXML.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				String path = setFileLoadChooser("xml");
				if(path!=null)
					MainController.loadXML(path);
			}
		});
		
		menuExportLibrary = new JMenu("Export Library");
		menuOption.add(menuExportLibrary);
		
		menuJson = new JMenuItem("JSON");
		menuExportLibrary.add(menuJson);
		menuJson.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				String path = setSaveChooser(".json");
				if(path!=null)
					MainController.saveJSON(path);
			}
		});
		
		menuXml = new JMenuItem("XML");
		menuExportLibrary.add(menuXml);
		menuXml.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				String path = setSaveChooser(".xml");
				if(path!=null)
					MainController.saveXML(path);
			}
		});
		
		menuOrganizeMoviesLibrary = new JMenuItem("Organize Movies Library");
		menuOption.add(menuOrganizeMoviesLibrary);
		menuOrganizeMoviesLibrary.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				String path = setDirectoryChooser();
				if(path!=null){
					MainController.orderMovies(path);
				}
			}
		});
	}
	
	/***
	 * Set Movie Panel
	 */
	private void SetMoviePanel(){
		innerPanel = new JPanel();
		innerPanel.setBackground(Color.GRAY);
		innerRightScrollPanel.setViewportView(innerPanel);
		innerPanel.setLayout(null);
		
		separator = new JSeparator();
		separator.setBounds(20, 65, 800, 12);
		innerPanel.add(separator);
		
		plotTextArea = new JTextArea();
		plotTextArea.setText("-");
		plotTextArea.setWrapStyleWord(true);
		plotTextArea.setLineWrap(true);
		plotTextArea.setBackground(Color.GRAY);
		plotTextArea.setBounds(20, 102, 711, 36);
		innerPanel.add(plotTextArea);
		
		releaseLabel = new JLabel("Release");
		releaseLabel.setFont(new Font("Lucida Grande", Font.BOLD, 15));
		releaseLabel.setBounds(110, 150, 70, 36);
		innerPanel.add(releaseLabel);
		
		dvdLabel = new JLabel("DVD:");
		dvdLabel.setBounds(110, 183, 32, 16);
		innerPanel.add(dvdLabel);
		
		lblTheatre = new JLabel("Theatre:");
		lblTheatre.setBounds(110, 198, 61, 16);
		innerPanel.add(lblTheatre);
		
		dvdRelease = new JLabel("-");
		dvdRelease.setBounds(149, 183, 82, 16);
		innerPanel.add(dvdRelease);
		
		theatreRelease = new JLabel("-");
		theatreRelease.setBounds(170, 198, 82, 16);
		innerPanel.add(theatreRelease);
		
		lblRuntime = new JLabel("Runtime:");
		lblRuntime.setFont(new Font("Lucida Grande", Font.BOLD, 15));
		lblRuntime.setBounds(20, 254, 82, 16);
		innerPanel.add(lblRuntime);
		
		runtime = new JLabel("-");
		runtime.setBounds(101, 255, 82, 16);
		innerPanel.add(runtime);
		
		plotLabel = new JLabel("Plot");
		plotLabel.setFont(new Font("Lucida Grande", Font.BOLD, 15));
		plotLabel.setBounds(20, 82, 61, 16);
		innerPanel.add(plotLabel);
		
		poster = new JLabel();
		poster.setBounds(832, 65, 312, 475);
		innerPanel.add(poster);
		
		ratingLabel = new JLabel("Ratings");
		ratingLabel.setFont(new Font("Lucida Grande", Font.BOLD, 15));
		ratingLabel.setBounds(275, 161, 96, 16);
		innerPanel.add(ratingLabel);
		
		criticsLabel = new JLabel("Critics:");
		criticsLabel.setBounds(275, 183, 61, 16);
		innerPanel.add(criticsLabel);
		
		audienceLabel = new JLabel("Audience:");
		audienceLabel.setBounds(275, 198, 70, 16);
		innerPanel.add(audienceLabel);
		
		critics = new JLabel("-");
		critics.setBounds(348, 183, 61, 16);
		innerPanel.add(critics);
		
		audience = new JLabel("-");
		audience.setBounds(348, 198, 61, 16);
		innerPanel.add(audience);
		
		ratingImage = new JLabel("New label");
		ratingImage.setBounds(20, 153, 61, 84);
		try {
			ratingImage.setIcon(new ImageIcon(ImageIO.read(this.getClass().getClassLoader().getResource("popcorn.png"))));
		} catch (IOException e) {
			e.printStackTrace();
		}
		innerPanel.add(ratingImage);
		
		criticLabel = new JLabel("Critic");
		criticLabel.setFont(new Font("Lucida Grande", Font.BOLD, 15));
		criticLabel.setBounds(431, 160, 61, 16);
		innerPanel.add(criticLabel);
		
		critic = new JTextArea();
		critic.setText("-");
		critic.setWrapStyleWord(true);
		critic.setLineWrap(true);
		critic.setBackground(Color.GRAY);
		critic.setBounds(431, 183, 373, 102);
		innerPanel.add(critic);
		
		imageCritic = new JLabel("");
		imageCritic.setBounds(743, 100, 77, 77);
		innerPanel.add(imageCritic);
		
		genreLabel = new JLabel("Genre:");
		genreLabel.setFont(new Font("Lucida Grande", Font.BOLD, 15));
		genreLabel.setBounds(20, 290, 61, 16);
		innerPanel.add(genreLabel);
		
		genres = new JLabel("-");
		genres.setBounds(80, 290, 61, 16);
		innerPanel.add(genres);
		
		actorsLabel = new JLabel("Actors:");
		actorsLabel.setFont(new Font("Lucida Grande", Font.BOLD, 15));
		actorsLabel.setBounds(20, 325, 61, 16);
		innerPanel.add(actorsLabel);
		
		actors = new JLabel("-");
		actors.setBounds(81, 325, 61, 16);
		innerPanel.add(actors);
		
		lblNewLabel = new JLabel("Director(s):");
		lblNewLabel.setFont(new Font("Lucida Grande", Font.BOLD, 15));
		lblNewLabel.setBounds(20, 362, 96, 16);
		innerPanel.add(lblNewLabel);
		
		directors = new JLabel("-");
		directors.setBounds(119, 362, 61, 16);
		innerPanel.add(directors);
		
		labelWriters = new JLabel("writer(s):");
		labelWriters.setFont(new Font("Lucida Grande", Font.BOLD, 15));
		labelWriters.setBounds(20, 400, 82, 18);
		innerPanel.add(labelWriters);
		
		writers = new JLabel("-");
		writers.setBounds(101, 401, 61, 17);
		innerPanel.add(writers);
		
		classifiedLabel = new JLabel("Classified:");
		classifiedLabel.setFont(new Font("Lucida Grande", Font.BOLD, 15));
		classifiedLabel.setBounds(20, 440, 82, 16);
		innerPanel.add(classifiedLabel);
		
		classified = new JLabel("-");
		classified.setBounds(110, 441, 61, 16);
		innerPanel.add(classified);
		
		productionLabel = new JLabel("Production:");
		productionLabel.setFont(new Font("Lucida Grande", Font.BOLD, 15));
		productionLabel.setBounds(431, 441, 96, 16);
		innerPanel.add(productionLabel);
		
		production = new JLabel("-");
		production.setBounds(528, 441, 61, 16);
		innerPanel.add(production);
		
		boxOfficeLabel = new JLabel("Box Office :");
		boxOfficeLabel.setFont(new Font("Lucida Grande", Font.BOLD, 15));
		boxOfficeLabel.setBounds(20, 479, 96, 16);
		innerPanel.add(boxOfficeLabel);
		
		boxOffice = new JLabel("-");
		boxOffice.setBounds(120, 480, 60, 16);
		innerPanel.add(boxOffice);
		
		titleLabel = new JLabel("Welcome to Woovee !");
		titleLabel.setFont(new Font("Lucida Grande", Font.PLAIN, 30));
		titleLabel.setBounds(20, 29, 416, 27);
		innerPanel.add(titleLabel);
	}
	
	/**
	 * Set the directory chooser
	 */
	public String setDirectoryChooser(){
		dialogue = new JFileChooser();
		dialogue.setDialogType(JFileChooser.OPEN_DIALOG);
		dialogue.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
		if (dialogue.showOpenDialog(null)== JFileChooser.APPROVE_OPTION) {
			    File file = dialogue.getSelectedFile();
			    return file.getAbsolutePath();
		}
		return null;
	}
	
	/**
	 * Set the save chooser
	 */
	public String setSaveChooser(String ext){
		saveDialogue = new JFileChooser();
		saveDialogue.setDialogType(JFileChooser.OPEN_DIALOG);
		saveDialogue.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
		FileFilter ff = new FileFilter(){
			public boolean accept(File f){
				if(f.isDirectory()) return true;
				else if(f.getName().endsWith(".xml")) return true;
				else if(f.getName().endsWith(".json")) return true;
				else return false;
			}
			public String getDescription(){
				return "JSON/XML files";
			}
		};
		saveDialogue.setFileFilter(ff);
		if (saveDialogue.showSaveDialog(null)== JFileChooser.APPROVE_OPTION) {
			    File file = saveDialogue.getSelectedFile();
			    return file.getAbsolutePath()+ext;
		}
		return null;
	}
	
	/**
	 * Set the file load chooser
	 */
	public String setFileLoadChooser(final String type){
		loadDialogue = new JFileChooser();
		loadDialogue.setDialogType(JFileChooser.OPEN_DIALOG);
		loadDialogue.setFileSelectionMode(JFileChooser.FILES_ONLY);
		FileFilter ff = new FileFilter(){
			public boolean accept(File f){
				if(f.isDirectory()) return true;
				else if(f.getName().endsWith("."+type+"")) return true;
				else return false;
			}
			public String getDescription(){
				return type+" files";
			}
		};
		loadDialogue.setFileFilter(ff);
		if (loadDialogue.showOpenDialog(null)== JFileChooser.APPROVE_OPTION) {
			    File file = loadDialogue.getSelectedFile();
			    return file.getAbsolutePath();
		}
		return null;
	}
	
	/***
	 * Set the movie info 
	 * @param movie
	 */
	public void SetMovieInfo(final Movie movie){
		titleLabel.setText(movie.getTitle()+" - "+String.valueOf((movie.getYear())));
		titleLabel.setSize(titleLabel.getPreferredSize());
		
		plotTextArea.setText(movie.getPlot());
		
		dvdRelease.setText(movie.getRelease().getDvd());
		
		theatreRelease.setText(movie.getRelease().getTheatre());
		
		runtime.setText(movie.getRuntime());
		
		try {
			url = new URL(movie.getPoster());
		} catch (MalformedURLException e) {
			e.printStackTrace();
		}
		try {
			image = ImageIO.read(url);
			poster.setIcon(new ImageIcon(image));
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		critics.setText(Float.toString(movie.getRating().getTomatoMeter())+"/10");
		
		audience.setText(Float.toString(movie.getRating().getTomatoUserMeter())+"/10");
		
		critic.setText(movie.getRating().getCritic());
		
	    try {
	    	imageCritic.setIcon(new ImageIcon(ImageIO.read(this.getClass().getClassLoader().getResource(movie.getRating().getTomatoImage()+".png"))));
		} catch (IOException e) {
			e.printStackTrace();
		}
	    
	    genres.setText(movie.genres());
	    genres.setSize(genres.getPreferredSize());
	    
	    actors.setText(movie.actors());
	    actors.setSize(actors.getPreferredSize());
	    
	    directors.setText(movie.directors());
	    directors.setSize(directors.getPreferredSize());
	    
	    writers.setText(movie.writers());
	    writers.setSize(writers.getPreferredSize());
	    
	    classified.setText(movie.getClassification());
	    
	    production.setText(movie.getProduction());
	    production.setSize(production.getPreferredSize());
	    
	    boxOffice.setText(movie.getBoxOffice());
	    boxOffice.setSize(boxOffice.getPreferredSize());
	
	}

	/**
	 * Update movies list
	 * @param array
	 */
	public void updateList(String[] array) {
		this.array=array;
		list.setListData(array);
	}

	/***
	 * Update movies not found list
	 * @param moviesNotFound
	 */
	public void updateListMoviesNotFound(String[] moviesNotFound) {
		this.arrayMovieNotFound=moviesNotFound;
		movieNotFoundList.setListData(moviesNotFound);
	}
}
